import { Color, Component, NodePool, Sprite, UITransform, Vec3, _decorator, instantiate, math, tween } from "cc";
import { MathUtil } from "../../../game/lib/kgame/util/MathUtil";
import { GameMgr } from "../GameMgr";
import { Snake } from "./Snake";
const { ccclass } = _decorator;

/**
 * 蛇身实体
 */
@ccclass("SnakeBody")
export class SnakeBody extends Component {

    /** 对象池 */
    static HEAD_POOL = new NodePool(SnakeBody);
    static BODY_POOL = new NodePool(SnakeBody);

    static get(idx: number) {
        if (idx === 0) {
            return (SnakeBody.HEAD_POOL.get() || instantiate(GameMgr.ins.headPrefab)).getComponent(SnakeBody)
        }
        return (SnakeBody.BODY_POOL.get() || instantiate(GameMgr.ins.bodyPrefab)).getComponent(SnakeBody)
    }

    static put(body: SnakeBody) {
        if (body.data.idx === 0) {
            SnakeBody.HEAD_POOL.put(body.node);
        } else {
            SnakeBody.BODY_POOL.put(body.node);
        }
    }

    snake: Snake;
    data: kp_entity_snakeBody;
    /** 实际位置 */
    pos: Vec3;
    /** 实际角度 */
    ang: number;
    /** 实际大小 */
    size: number;
    /** 颜色 */
    color = new Color();


    /**
     * 初始化
     * @param snakeId
     * @param data
     * @param size
     */
    onInit(snake: Snake, data: kp_entity_snakeBody, size: number) {
        this.node.name = data.idx + "";
        this.snake = snake;
        this.data = data;
        this.pos = new Vec3(data.x, data.y);
        this.node.angle = this.ang = MathUtil.rad2Deg(data.rot);
        this.node.setPosition(this.pos);
        this.updateSize(size);
        this.updateColor();
        return this;
    }

    reuse() {

    }

    unuse() {
        this.snake = null;
        this.data = null;
        this.getComponent(UITransform).priority = -1;
    }

    tweenScale = new Vec3();

    onRemove() {
        this.tweenScale.set(0, 0);
        tween(this.node)
            .to(0.2, { scale: this.tweenScale }, { easing: "quadOut" })
            .call(() => SnakeBody.put(this))
            .start()
    }

    /**
     * 更新数据
     * @param data 
     */
    updateData(data: kp_entity_snakeBody) {
        this.data = data;
        this.pos.set(data.x, data.y);
        this.ang = MathUtil.rad2Deg(data.rot);
    }

    /**
     * 更新大小
     * @param size 
     */
    updateSize(size: number) {
        this.size = size;
    }

    /**
     * 更新颜色
     */
    updateColor() {
        const { colors } = this.snake.data;
        this.color.fromHEX(colors[this.data.idx % colors.length].toString(16));
        this.color.a = this.snake.data.ghost ? 128 : 255;
        this.getComponent(Sprite).color = this.color;
    }

    update(dt: number) {
        const smooth = 10 * dt;
        const { position } = this.node;
        this.node.setPosition(
            math.lerp(position.x, this.pos.x, smooth),
            math.lerp(position.y, this.pos.y, smooth)
        );
        const diff = MathUtil.degDiff(this.node.angle, this.ang);
        this.node.angle = math.lerp(this.node.angle, this.node.angle + diff, dt * 10);
        const scale = math.lerp(this.node.scale.x, this.size, smooth);
        this.node.setScale(scale, scale);
    }

}